<script setup lang="ts">
import {
  NForm,
  NFormItem,
  NInput,
  NButton,
  NIcon,
  NDataTable,
  type DataTableColumns,
  type UploadFileInfo,
  NSelect,
  NPagination,
  NImage,
  useMessage,
  NDatePicker,
  NInputNumber,
  NTreeSelect,
  type SelectOption
} from 'naive-ui'
import { h, onMounted, reactive, ref, computed } from 'vue'
import FixedAction from '@/components/FixedAction.vue'
import { ArrowRightAltFilled } from '@vicons/material'
import type { IdentifyInfoModel, IdentifySubItemModel } from '@/api/batch'
import type { BatchDetailModel } from '@/api/batchV2'
import { sendRequest } from '@/utils/api'
import type { HttpResponse, HttpResponsePagination } from '@/utils/http'
import { useRoute } from 'vue-router'
import useRouteReplace from '@/hooks/useRouteReplace'
import { useRouter } from 'vue-router'
import FileList from '@/components/FileList.vue'
import VBackImg from '@/assets/images/back.png'
import VAttachments from '@/views/OA/Common/Attachments.vue'

const router = useRouter()
const route = useRoute()
const routeReplace = useRouteReplace(route.query.redirect as string)
const message = useMessage()
const processInfo = ref(
  {} as {
    finish: boolean
    register: boolean
    submit: boolean
  }
)
const process = async (identifyId?: number) => {
  const [error, res] = await sendRequest({
    module: 'batch',
    api: 'identifyProcess',
    override: {
      params: {
        batchId: route.params.id,
        identifyId: identifyId || null
      }
    }
  })
  if (error) throw error
  if (res.code !== 0) throw new Error(res.msg)
  processInfo.value = res.data
  console.log(res)
}

const isTF = ref(true)
const routeIdentifyId = route.query.identifyId as string | undefined
const collectorName = ref<string | null>(null)
const batchFileList = ref<UploadFileInfo[]>([])
const batchInfo = ref({} as BatchDetailModel)
const isJCDG = computed(() => batchInfo.value.solicitMethodCode === 'A3007')
const queryBatchInfo = async () => {
  const [error, res] = await sendRequest<HttpResponse<BatchDetailModel>>({
    module: 'batchV2',
    api: 'detail',
    override: {
      params: {
        id: route.params.id
      }
    }
  })
  if (error) return message.error(error.message)

  sendRequest({
    module: 'clue',
    api: 'infoManage',
    uri: {
      id: res.data.clueId
    }
  })
    .then(([_, cr]) => {
      if (cr) {
        sendRequest({
          module: 'collector',
          api: 'info',
          uri: {
            id: cr.data.collectorId
          }
        })
          .then(([_, er]) => {
            if (er) collectorName.value = er.data.userName
          })
          .catch(() => (collectorName.value = null))
      }
    })
    .catch(() => (collectorName.value = null))

  if (res.data.endTime) {
    res.data.endTime = res.data.endTime.slice(0, 10)
  }
  if (res.data.startTime) {
    res.data.startTime = res.data.startTime.slice(0, 10)
  }
  if (res.data.solicitNum) {
    res.data.solicitNum = Number(res.data.solicitNum)
  }
  batchInfo.value = res.data
  if (res.data.fileIds) batchFileList.value = await queryFileList(res.data.fileIds)
}

const identifyList = ref<IdentifyInfoModel[]>([])
const queryIdentifyList = async () => {
  try {
    const [error, res] = await sendRequest<HttpResponse<IdentifyInfoModel[]>>({
      module: 'batch',
      api: 'identifyList',
      override: {
        params: {
          batchId: route.params.id
          // identifyTypeCode: batchInfo.value.identifyTypeCode
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    identifyList.value = res.data
    identifyList.value.forEach((e) => {
      if (!e.identifyTime) return
      e.identifyTime = e.identifyTime.split(' ')[0]
    })
    identifyList.value.forEach(async (e) => {
      e._files = await queryFileList(e.fileIds)
    })
    if (routeIdentifyId) handleUpdateIdentityId(Number(routeIdentifyId))
    if (res.data.length > 0) {
      // @ts-ignore
      handleUpdateIdentityId(res.data.find((e) => e.id === routeIdentifyId)?.id || res.data[0].id)
    }
  } catch (error) {
    console.error(error)
  }
}

const identifyId = ref<number | null>(null)
const attachments = ref({} as any)
const identifyInfo = ref({} as IdentifyInfoModel)
const identifySumItemTableData = ref<IdentifySubItemModel[]>([])
const inventoryTableData = ref<IdentifySubItemModel[]>([])

const identifySumItemLoading = ref(false)
const inventoryLoading = ref(false)

const sumItemPaginationReactive = reactive({
  page: 1,
  pageSize: 10,
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100, 500],
  itemCount: 0,
  onChange: (page: number) => {
    sumItemPaginationReactive.page = page
    queryIdentifySumItemTableData()
  },
  onUpdatePageSize: (pageSize: number) => {
    sumItemPaginationReactive.pageSize = pageSize
    sumItemPaginationReactive.page = 1
    queryIdentifySumItemTableData()
  }
})
const inventoryPaginationReactive = reactive({
  page: 1,
  pageSize: 10,
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100, 500],
  itemCount: 0,
  onChange: (page: number) => {
    inventoryPaginationReactive.page = page
    queryInventoryTableData()
  },
  onUpdatePageSize: (pageSize: number) => {
    inventoryPaginationReactive.pageSize = pageSize
    inventoryPaginationReactive.page = 1
    queryInventoryTableData()
  }
})

const columns: DataTableColumns<IdentifySubItemModel> = [
  {
    title: '序号',
    key: 'index',
    width: 80,
    align: 'center',
    render: (_, index) =>
      sumItemPaginationReactive.pageSize * (sumItemPaginationReactive.page - 1) + index + 1
  },
  {
    title: '征集品编码',
    key: 'subItemCode'
  },
  {
    title: '征集品名称',
    key: 'itemName'
  },
  {
    title: '类型',
    key: 'itemType'
  },
  {
    title: '征集品真伪',
    key: 'authenticity',
    render(e) {
      if (!e.authenticity) return '/'
      return e.authenticity === '0' ? '真' : e.authenticity === '1' ? '伪' : '无法确定'
    }
  },
  {
    title: '意见',
    key: 'opinion'
  }
]

const listColumns: DataTableColumns<IdentifySubItemModel> = [
  {
    title: '序号',
    key: 'index',
    width: 80,
    align: 'center',
    render: (_, index) =>
      sumItemPaginationReactive.pageSize * (sumItemPaginationReactive.page - 1) + index + 1
  },
  {
    title: '征集品编码',
    key: 'subItemCode'
  },
  {
    title: '征集品名称',
    key: 'itemName'
  },
  {
    title: '类型',
    key: 'itemType'
  },
  {
    title: '接收时间',
    key: 'receiveTime'
  },
  {
    title: '移交人',
    key: 'transferUser'
  },
  {
    title: '操作',
    key: 'action',
    align: 'center',
    render(e) {
      return h(
        NButton,
        {
          type: 'primary',
          size: 'small',
          quaternary: true,
          onClick: () => {
            router.push({
              name: 'collectDetail',
              params: {
                id: e.itemId
              },
              query: {
                type: 'detail',
                subItemId: e.id,
                redirect: route.fullPath,
                identifyId: identifyId.value,
                isTF: isTF.value ? 'true' : 'false'
              }
            })
          }
        },
        {
          default: () => '详情'
        }
      )
    }
  }
]

const queryIdentifySumItemTableData = async () => {
  try {
    identifySumItemLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<IdentifySubItemModel>>({
      module: 'batch',
      api: 'identifySubItems',
      override: {
        params: {
          identifyId: identifyId.value,
          limit: sumItemPaginationReactive.pageSize,
          page: sumItemPaginationReactive.page
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    identifySumItemTableData.value = res.data.list
    sumItemPaginationReactive.itemCount = res.data.totalCount
  } catch (error) {
    console.error(error)
  } finally {
    identifySumItemLoading.value = false
  }
}

const clueSelectOptions = ref<SelectOption[]>([])
const clueSelectLoading = ref(false)
const queryClueSelectOptions = async () => {
  clueSelectLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<any[]>>({
      module: 'batchV2',
      api: 'clueList'
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueSelectOptions.value = res.data
  } catch (error) {
    console.error(error)
  } finally {
    clueSelectLoading.value = false
  }
}

const queryInventoryTableData = async () => {
  try {
    inventoryLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<IdentifySubItemModel>>({
      module: 'batch',
      api: 'identifySubItems',
      override: {
        params: {
          identifyId: identifyId.value
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    inventoryTableData.value = res.data.list
  } catch (error) {
    console.error(error)
  } finally {
    inventoryLoading.value = false
  }
}

const queryAttachments = async () => {
  try {
    const [error, res] = await sendRequest<HttpResponse>({
      module: 'batch',
      api: 'identifyRegisterDetail',
      override: {
        params: {
          identifyId: identifyId.value
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    attachments.value = res.data
    filesData.forEach((e) => {
      const files = res.data[e.key]
      if (!files) return (e.files = [])
      e.files = files.map((e: any) => ({
        id: e.id,
        name: e.name,
        status: 'finished',
        url: e.path
      }))
    })
  } catch (error) {
    console.error(error)
  }
}

const clueMethodOptions = reactive<any[]>([])
const clueMethodLoading = ref(false)
const queryClueMethodOptions = async () => {
  clueMethodLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<any[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A30'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueMethodOptions.length = 0
    clueMethodOptions.push(...(res.data[0] ? res.data[0].children || [] : []))
  } catch (error) {
    console.error(error)
  } finally {
    clueMethodLoading.value = false
  }
}

const handleUpdateIdentityId = (id: number) => {
  process(id)
  identifyId.value = id
  queryIdentifySumItemTableData()
  queryInventoryTableData()
  queryAttachments()

  const identify = identifyList.value.find((e) => e.id === id)
  if (identify) {
    identifyInfo.value = identify
    isTF.value = identify.identifyTypeCode === 'A3101'
  }
}

const queryFileList = async (filesIds: string): Promise<UploadFileInfo[]> => {
  try {
    const [error, res] = await sendRequest<
      HttpResponse<
        {
          name: string
          path: string
          id: string
        }[]
      >
    >({
      module: 'upload',
      api: 'list',
      override: {
        params: {
          ids: filesIds
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    return res.data.map((e) => ({
      id: e.id,
      name: e.name,
      status: 'finished',
      url: e.path
    }))
  } catch (error) {
    return []
  }
}

const filesData = reactive<
  {
    label: string
    key: string
    files: UploadFileInfo[]
  }[]
>([
  {
    label: '鉴定方案',
    key: 'planFiles',
    files: []
  },
  {
    label: '专家鉴定意见',
    key: 'expertFiles',
    files: []
  },
  {
    label: '汇总鉴定意见',
    key: 'summaryResultFiles',
    files: []
  },
  {
    label: '会议汇报材料',
    key: 'meetingResultFiles',
    files: []
  },
  {
    label: '会议纪要材料',
    key: 'meetingMinutesFiles',
    files: []
  },
  {
    label: '合同和发票材料',
    key: 'contractFiles',
    files: []
  },
  {
    label: '视频材料',
    key: 'videoFiles',
    files: []
  },
  {
    label: '音频材料',
    key: 'audioFiles',
    files: []
  },
  {
    label: '其他材料',
    key: 'otherFiles',
    files: []
  },
  {
    label: '价格结果材料',
    key: 'priceFiles',
    files: []
  },
  {
    label: '谈判会材料',
    key: 'talkFiles',
    files: []
  }
  // {
  //   label: '补充登记材料',
  //   key: 'supplementFiles',
  //   files: []
  // }
])

onMounted(async () => {
  queryClueMethodOptions()
  queryClueSelectOptions()
  await queryBatchInfo()
  await Promise.allSettled([queryIdentifyList()])
})
</script>

<template>
  <DetailFormProvider>
    <div class="batch-detail">
      <div class="bd-title">鉴定流程</div>
      <div class="bd-flow bd-card">
        <div
          class="step"
          :class="{ finished: processInfo.submit }"
        >
          提交鉴定
        </div>
        <NIcon
          color="#6CB187"
          size="32"
        >
          <ArrowRightAltFilled />
        </NIcon>
        <div
          class="step"
          :class="{ finished: processInfo.register }"
        >
          鉴定登记
        </div>
        <NIcon
          color="#6CB187"
          size="32"
        >
          <ArrowRightAltFilled />
        </NIcon>
        <div
          class="step"
          :class="{ finished: processInfo.finish }"
        >
          鉴定结束
        </div>
      </div>

      <div class="br"></div>

      <div class="bd-title">批次信息</div>
      <DetailFormProvider>
        <NForm
          disabled
          label-placement="left"
          label-width="100rem"
          :show-feedback="false"
          :show-require-mark="false"
          class="bd-card form"
        >
          <NFormItem label="关联线索：">
            <NSelect
              :value="batchInfo.clueId"
              :options="clueSelectOptions"
              :loading="clueSelectLoading"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="批次名称：">
            <NInput
              :value="batchInfo.name"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="征集方式：">
            <NTreeSelect
              :value="batchInfo.solicitMethodCode"
              :options="clueMethodOptions"
              :loading="clueMethodLoading"
              placeholder="/"
              key-field="code"
              label-field="name"
            />
          </NFormItem>
          <NFormItem label="接收时间：">
            <NDatePicker
              :formatted-value="batchInfo.receiveTime"
              type="datetime"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="接收人：">
            <NInput
              :value="batchInfo.receiver"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="征集数量：">
            <NInputNumber
              :value="batchInfo.solicitNum"
              placeholder="/"
              :show-button="false"
              :min="0"
              :max="Number.MAX_SAFE_INTEGER"
            />
          </NFormItem>
          <NFormItem label="证书发放：">
            <NInput
              :value="batchInfo.certificateType"
              placeholder="/"
            >
              <template #suffix>
                <NButton
                  v-if="batchInfo.certificateType"
                  color="#6CB187"
                  ghost
                  size="small"
                  @click="
                    $router.push({
                      name: 'DonationCertificateDetail',
                      params: { id: batchInfo.certificateId }
                    })
                  "
                >
                  查看详情
                </NButton>
              </template>
            </NInput>
          </NFormItem>
          <template v-if="isJCDG">
            <NFormItem label="开始时间：">
              <NDatePicker
                :formatted-value="batchInfo.startTime"
                type="date"
                placeholder="/"
              />
            </NFormItem>
            <NFormItem label="结束时间：">
              <NDatePicker
                :formatted-value="batchInfo.endTime"
                type="date"
                placeholder="/"
              />
            </NFormItem>
            <NFormItem label="代存期限：">
              <NInput
                :value="batchInfo.depositPeriod"
                placeholder="/"
              />
            </NFormItem>
          </template>

          <NFormItem label="藏家：">
            <NInput
              v-model:value="collectorName"
              placeholder="/"
              disabled
            />
          </NFormItem>
          <NFormItem label="移交人：">
            <NInput
              v-model:value="batchInfo.transferor"
              placeholder="/"
              disabled
              style="flex-shrink: 2"
            />
            <NInput
              v-model:value="batchInfo.transferorPhone"
              placeholder="/"
              disabled
            />
          </NFormItem>

          <NFormItem label="创建时间：">
            <NDatePicker
              :formatted-value="batchInfo.createTime"
              type="datetime"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="修改时间：">
            <NDatePicker
              :formatted-value="batchInfo.modifyTime"
              type="datetime"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem label="鉴定状态：">
            <NInput
              :value="batchInfo.identifyStatus"
              placeholder="/"
            />
          </NFormItem>
          <NFormItem
            label="备注："
            class="n-form-item--textarea"
          >
            <NInput
              :value="batchInfo.remark"
              type="textarea"
              placeholder="/"
              rows="5"
            />
          </NFormItem>
          <NFormItem label="附件：">
            <VAttachments
              v-if="batchInfo.fileIds"
              :attach-list="batchFileList"
            />
          </NFormItem>
        </NForm>
      </DetailFormProvider>

      <div class="br"></div>

      <div class="bd-content">
        <div class="bd-title">鉴定信息</div>
        <NForm
          disabled
          label-placement="left"
          label-width="100rem"
          class="bd-card grid grid-4"
        >
          <NFormItem label="鉴定编号：">
            <NSelect
              :options="identifyList"
              :disabled="false"
              placeholder="/"
              value-field="id"
              label-field="identifyCode"
              :value="identifyId"
              @update:value="handleUpdateIdentityId"
            />
          </NFormItem>
          <NFormItem label="鉴定名称：">
            <NInput
              placeholder="/"
              :value="identifyInfo.identifyName"
            />
          </NFormItem>
          <NFormItem label="鉴定日期：">
            <NInput
              placeholder="/"
              :value="identifyInfo.identifyTime"
            />
          </NFormItem>
          <NFormItem label="鉴定地点：">
            <NInput
              placeholder="/"
              :value="identifyInfo.identifyAddress"
            />
          </NFormItem>
          <NFormItem label="鉴定类型：">
            <NInput
              placeholder="/"
              :value="identifyInfo.identifyType"
            />
          </NFormItem>
          <NFormItem
            label="鉴定专家："
            style="grid-column: 2 / span 2"
          >
            <NInput
              placeholder="/"
              :value="identifyInfo.identifyExperts?.join('，')"
            />
          </NFormItem>
          <NFormItem label="描述：">
            <NInput
              placeholder="/"
              type="textarea"
              :value="identifyInfo.identifyDescription"
              rows="1"
            />
          </NFormItem>
          <NFormItem
            label="附件："
            style="grid-column: 1 / -1"
          >
            <FileList
              v-if="identifyInfo.fileIds"
              :file-list="identifyInfo._files"
            />
            <!-- <NUpload
            v-if="identifyInfo.fileIds"
            abstract
            :file-list="identifyInfo._files"
          >
            <NUploadFileList />
          </NUpload> -->
          </NFormItem>
        </NForm>

        <div class="br"></div>

        <template v-if="isTF">
          <div class="bd-title">汇总结果</div>
          <NForm
            disabled
            label-placement="left"
            label-width="120rem"
            :show-feedback="false"
            inline
            class="bd-card grid grid-3"
          >
            <NFormItem label="鉴定汇总意见：">
              <NInput
                placeholder="/"
                :value="attachments.totalOpinion"
              />
            </NFormItem>
            <NFormItem label="备注：">
              <NInput
                placeholder="/"
                type="textarea"
                rows="1"
                :value="attachments.remark"
              />
            </NFormItem>
          </NForm>
          <NDataTable
            :loading="identifySumItemLoading"
            :data="identifySumItemTableData"
            :columns="columns"
            height="200rem"
            class="bd-card"
          />
          <NPagination
            class="bd-card"
            style="padding-top: 0"
            show-size-picker
            show-quick-jumper
            :page-sizes="sumItemPaginationReactive.pageSizes"
            :item-count="sumItemPaginationReactive.itemCount"
            :page="sumItemPaginationReactive.page"
            :page-size="sumItemPaginationReactive.pageSize"
            @update:page="sumItemPaginationReactive.onChange"
            @update:page-size="sumItemPaginationReactive.onUpdatePageSize"
          >
            <template #suffix>页</template>
            <template #prefix>
              <span style="font-size: 14px">共{{ sumItemPaginationReactive.itemCount }}条</span>
            </template>
          </NPagination>

          <div class="br"></div>
        </template>

        <div class="bd-title">鉴定清单</div>
        <NDataTable
          :loading="inventoryLoading"
          :data="inventoryTableData"
          :columns="listColumns"
          height="200rem"
          class="bd-card"
        />
        <NPagination
          class="bd-card"
          style="padding-top: 0"
          show-size-picker
          show-quick-jumper
          :page-sizes="inventoryPaginationReactive.pageSizes"
          :item-count="inventoryPaginationReactive.itemCount"
          :page="inventoryPaginationReactive.page"
          :page-size="inventoryPaginationReactive.pageSize"
          @update:page="inventoryPaginationReactive.onChange"
          @update:page-size="inventoryPaginationReactive.onUpdatePageSize"
        >
          <template #suffix>页</template>
        </NPagination>

        <div class="br"></div>

        <div class="bd-title">附件</div>
        <NForm
          class="bd-card attachment-grid"
          require-mark-placement="left"
          label-placement="left"
          disabled
        >
          <div
            v-for="item in filesData"
            :key="item.key"
            class="attachment"
          >
            <div class="attachment-title">{{ item.label }}</div>
            <NFormItem label="附件：">
              <FileList :file-list="item.files" />
            </NFormItem>
          </div>
        </NForm>
      </div>
    </div>
  </DetailFormProvider>

  <FixedAction>
    <div class="batch-detail-buttons">
      <NButton
        style="width: 78px; color: #5fb17f"
        ghost
        @click="routeReplace"
      >
        <template #icon>
          <NImage
            :src="VBackImg"
            style="width: 50rem; height: 50rem"
            preview-disabled
          ></NImage>
        </template>
        返回
      </NButton>
    </div>
  </FixedAction>
</template>

<style scoped lang="scss">
.batch-detail {
  min-height: 100%;
  padding: 15rem 0 110rem;
  background-color: #f0efee;

  .br {
    position: relative;
    width: 100%;
    padding: 30rem 0;

    &::after {
      content: '';
      position: absolute;
      width: 100%;
      top: 50%;
      left: 0;
      border-top: 1px dotted #bc9e70;
      transform: translateY(-50%);
    }
  }

  .bd-card {
    padding: 20rem;
    background-color: #e1e1e1;

    &.form {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 16rem 32rem;

      .n-form-item--textarea {
        grid-column: 1 / -1;
      }

      .n-date-picker,
      .n-input-number {
        flex: 1;
      }
    }
  }

  .n-form.grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0 60rem;

    &.grid-3 {
      grid-template-columns: repeat(3, 1fr);
    }
    &.grid-4 {
      grid-template-columns: repeat(4, 1fr);
    }
  }

  .n-form.attachment-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10rem 15rem;
    padding: 20rem 30rem;

    .attachment {
      &-title {
        margin-bottom: 0.5em;
        font-weight: 600;
        font-size: 16rem;
      }

      .n-form-item {
        margin-left: 2em;
      }
    }
  }

  .bd-title {
    font-size: 26rem;
    margin-bottom: 30rem;
    color: #048c5e;
    line-height: 1;
  }

  .bd-flow {
    display: flex;
    align-items: center;
    padding: 20rem 20rem 30rem;
    gap: 0 1.5em;

    .step {
      padding: 10rem 15rem;
      background-color: #e1e1e1;

      &.finished {
        color: #fff;
        background-color: #6cb187;
      }
    }
  }
}

.batch-detail-buttons {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0 16rem;
}
</style>
